﻿using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace Persistence
{
	public class Storage
	{
		public static void LoadWorld()
		{
			try
			{
				FileStream fs = OpenLastWorldDB();

				if (fs == null)
				{
					Logger.LogWarning("No world database found.");
					return;
				}

				BinaryFormatter myBF = new BinaryFormatter();
				World w = myBF.Deserialize(fs) as World;

				World.LoadWorld(w);
			}
			catch (Exception ex)
			{
				Logger.LogError("Error loading world: " + ex.Message);
			}
		}

		private static FileStream OpenLastWorldDB()
		{
			// Loads the latest world database so far.
			DirectoryInfo di = new DirectoryInfo(GetWorldDir());

			FileInfo[] files = di.GetFiles("world*.dat", SearchOption.TopDirectoryOnly);

			if (files.Length == 0)
				return null;

			Array.Sort(files, delegate(FileInfo f1, FileInfo f2) { return f2.CreationTime.CompareTo(f1.CreationTime); });

			return new FileStream(files[0].FullName, FileMode.Open, FileAccess.Read);
		}


		/// <summary>
		/// Updates the world database to disk.
		/// </summary>
		public static void UpdateWorld()
		{
			string pathName = GetDatedRandomFileName();
			FileStream fs = OpenFileForWriting(pathName);
			BinaryFormatter myBF = new BinaryFormatter();


			// Serialize World.
			myBF.Serialize(fs, World.Current);			
			
			fs.Flush();
			fs.Close();
		}

		private static FileStream OpenFileForWriting(string path)
		{
			return new FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None);
		}
		
		private static string GetWorldDir()
		{
			return ConfigurationManager.AppSettings["DATA_DIR"];
		}

		private static string GetPlayerDir()
		{
			return ConfigurationManager.AppSettings["PLAYER_DIR"];
		}


		private static string GetDatedRandomFileName()
		{
			for(int i = 0; i < 3; i++)
			{
				string path = Path.Combine(ConfigurationManager.AppSettings["DATA_DIR"],
					"world - " +
					DateTime.Now.ToString("dd-MM-yyyy-HHmmss") +
					" - " + Path.GetRandomFileName().Replace(".", "") + ".dat");

				if (!File.Exists(path))
				{
					return path;
				}
			}

			throw new InvalidOperationException("Unable to Generate random file name.");
		}
	}
}
